# python基本数据类型
"""
Number（数字）
    int、float、bool、complex（复数）
String（字符串）
List（列表）
Tuple（元组）
Set（集合）
Dictionary（字典）


不可变数据（3 个）：Number（数字）、String（字符串）、Tuple（元组）
可变数据（3 个）：List（列表）、Dictionary（字典）、Set（集合）
"""

# Number（数字）
print('#' * 15 + '数字' + '#' * 15)

# int、float、bool、complex（复数）
a, b, c, d = 20, 5.5, True, 4+3j
print(type(a), type(b), type(c), type(d))
print(isinstance(a, int),
      isinstance(b, float),
      isinstance(c, bool),
      isinstance(d, complex))

# del语句删除一些对象引用
del a

# 数值运算
print(5 + 4)  # 加法
print(4.3 - 2)  # 减法
print(3 * 7)  # 乘法
print(2 / 4)  # 除法，得到一个浮点数
print(2 // 4)  # 除法，得到一个整数
print(17 % 3)  # 取余
print(2 ** 5)  # 乘方


# 字符串
print('#' * 15 + '字符串' + '#' * 15)
"""
Python中的字符串用单引号 ' 或双引号 " 括起来，同时使用反斜杠 \ 转义特殊字符。
Python 没有单独的字符类型，一个字符就是长度为1的字符串。
"""
s = 'test_str'

print(s)          # 输出字符串
print(s[0:-1])    # 输出第一个到倒数第二个的所有字符
print(s[0])       # 输出字符串第一个字符
print(s[2:5])     # 输出从第三个开始到第五个的字符
print(s[2:])      # 输出从第三个开始的后的所有字符
print(s * 2)      # 输出字符串两次，也可以写成 print (2 * str)
print(s + "TEST")  # 连接字符串

# Python 使用反斜杠 \ 转义特殊字符，如果你不想让反斜杠发生转义，可以在字符串前面添加一个 r，表示原始字符串
# 反斜杠(\)可以作为续行符，表示下一行是上一行的延续。也可以使用 """...""" 或者 '''...''' 跨越多行。
print('Py\nthon')
print(r'Py\nthon')

# Python 字符串不能被改变。向一个索引位置赋值，比如word[0] = 'm'会导致错误。
word = 'Python'
print(word[0], word[5])
print(word[-1], word[-6])


# List（列表）
print('#' * 15 + '列表' + '#' * 15)
"""
列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同，它支持数字，字符串甚至可以包含列表（所谓嵌套）。
列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
加号 + 是列表连接运算符，星号 * 是重复操作
"""

test_list = ['abcd', 786, 2.23, 'runoob', 70.2]
tiny_list = [123, 'runoob']

print(test_list)            # 输出完整列表
print(test_list[0])         # 输出列表第一个元素
print(test_list[1:3])       # 从第二个开始输出到第三个元素
print(test_list[2:])        # 输出从第三个元素开始的所有元素
print(tiny_list * 2)    # 输出两次列表
print(test_list + tiny_list)  # 连接列表

# 与Python字符串不一样的是，列表中的元素是可以改变的
a = [1, 2, 3, 4, 5, 6]
print(a[0])
a[2:5] = [13, 14, 15]
print(a)
a[2:5] = []
print(a)

# list = list[-1::-1] 可以逆转数组
a = ['1', '2', '3']
print(a[-1::-1])


# Tuple（元组）
print('#' * 15 + '元组' + '#' * 15)
"""
元组（tuple）与列表类似，不同之处在于元组的元素不能修改。元组写在小括号 () 里，元素之间用逗号隔开
元组中的元素类型也可以不相同
"""

test_tuple = ('abcd', 786, 2.23, 'runoob', 70.2)
tiny_tuple = (123, 'runoob')

print(test_tuple)             # 输出完整元组
print(test_tuple[0])          # 输出元组的第一个元素
print(test_tuple[1:3])        # 输出从第二个元素开始到第三个元素
print(test_tuple[2:])         # 输出从第三个元素开始的所有元素
print(tiny_tuple * 2)     # 输出两次元组
print(test_tuple + tiny_tuple)  # 连接元组

# 元组与字符串类似，可以被索引且下标索引从0开始，-1 为从末尾开始的位置。也可以进行截取
# 可以把字符串看作一种特殊的元组
tup = (1, 2, 3, 4, 5, 6)
print(tup[0])
print(tup[1:5])
# tup[0] = 11 修改元组元素的操作是非法的，会导致程序运行报错
# 虽然tuple的元素不可改变，但它可以包含可变的对象，比如list列表

# 构造包含 0 个或 1 个元素的元组比较特殊，所以有一些额外的语法规则
tup1 = ()    # 空元组
tup2 = (20, )  # 一个元素，需要在元素后添加逗号 tup = (20)不是构成一个元组而是int（tup2=20
# string、list 和 tuple 都属于 sequence（序列）。


# Set（集合）
print('#' * 15 + '集合' + '#' * 15)
"""
集合（set）是由一个或数个形态各异的大小整体组成的，构成集合的事物或对象称作元素或是成员。
基本功能是进行成员关系测试和删除重复元素。
可以使用大括号 { } 或者 set() 函数创建集合，注意：创建一个空集合必须用 set() 而不是 { }，因为 { } 是用来创建一个空字典。
"""

sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}
print(sites)   # 输出集合，重复的元素被自动去掉
# 成员测试
if 'Runoob' in sites:
    print('Runoob 在集合中')
else:
    print('Runoob 不在集合中')

# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(b)
print(a - b)     # a 和 b 的差集
print(a | b)     # a 和 b 的并集
print(a & b)     # a 和 b 的交集
print(a ^ b)     # a 和 b 中不同时存在的元素


# Dictionary（字典）
print('#' * 15 + '字典' + '#' * 15)
"""
字典（dictionary）是Python中另一个非常有用的内置数据类型。
列表是有序的对象集合，字典是无序的对象集合。两者之间的区别在于：字典当中的元素是通过键来存取的，而不是通过偏移存取。
字典是一种映射类型，字典用 { } 标识，它是一个无序的 键(key) : 值(value) 的集合。
键(key)必须使用不可变类型。
在同一个字典中，键(key)必须是唯一的。
字典是一种映射类型，它的元素是键值对。
字典的关键字必须为不可变类型，且不能重复。
创建空字典使用 { }或者dict()。
"""

test_dict = dict()  # 第二种构造字典方法 test_dict = {}
test_dict['one'] = "1 - 菜鸟教程"
test_dict[2] = "2 - 菜鸟工具"
tiny_dict = {'name': 'runoob','code': 1, 'site': 'www.runoob.com'}
print(test_dict['one'])       # 输出键为 'one' 的值
print(test_dict[2])           # 输出键为 2 的值
print(tiny_dict)          # 输出完整的字典
print(tiny_dict.keys())   # 输出所有键
print(tiny_dict.values())  # 输出所有值

# 构造函数 dict() 可以直接从键值对序列中构建字典如下
print(dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)]))
print({x: x**2 for x in (2, 4, 6)})
print(dict(Runoob=1, Google=2, Taobao=3))


# Python数据类型转换
print('#' * 15 + '数据类型转换' + '#' * 15)
"""
有时候，我们需要对数据内置的类型进行转换，数据类型的转换，你只需要将数据类型作为函数名即可。
"""

# int(x [,base]) 将x转换为一个整数
print(int())
print(int(3))
print(int(3.6))
print(int('12', 16))  # 如果是带参数base的话，12要以字符串的形式进行输入，12 为 16进制
print(int('0xa', 16))
print(int('10', 8))
# float(x) 将x转换到一个浮点数
print(float(1))
print(float('123'))
# complex(real [,imag]) 创建一个复数
print(complex(1, 2))
print(complex('1'))
print(complex('1+2j'))  # 这个地方在"+"号两边不能有空格，也就是不能写成"1 + 2j"，应该是"1+2j"，否则会报错
# str(x) 将对象 x 转换为字符串
print(str(123))
# repr(x) 将对象 x 转换为表达式字符串
print(repr('123'))
# eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象
x = 7
print(eval('3 * x'))
print(eval('pow(2,2)'))
# tuple(s) 将序列 s 转换为一个元组
print(tuple(['Google', 'Taobao', 'Runoob', 'Baidu']))
# list(s) 将序列 s 转换为一个列表
print(list(('Google', 'Taobao', 'Runoob', 'Baidu')))
# set(s) 转换为可变集合
print(set('aabcd'))
# dict(d) 创建一个字典。d 必须是一个 (key, value)元组序列。
print(dict(a=1, b=2))
# frozenset(s) 转换为不可变集合
print(frozenset(range(10)))
# chr(x) 将一个整数转换为一个字符
print(chr(0x30), chr(0x31), chr(0x61), chr(48), chr(49), chr(97))
# ord(x) 将一个字符转换为它的整数值
print(ord('a'))
# hex(x) 将一个整数转换为一个十六进制字符串
print(hex(255))
print(type(hex(12)))
# oct(x) 将一个整数转换为一个八进制字符串
print(oct(10))
